<!-- 定时任务配置页面 -->
<template>
  <div class="scheduler-config-panel">
    <div class="scheduler-header">
      <h2>{{ t('config.schedulerConfig.title') }}</h2>
      <button class="action-btn" @click="showAddModal = true">
        <Icon icon="carbon:add" />
        {{ t('config.schedulerConfig.addJob') }}
      </button>
    </div>
    <div class="search-box">
      <input v-model="searchQuery" :placeholder="t('config.schedulerConfig.searchPlaceholder')" class="search-input" />
      <span class="search-icon">🔍</span>
    </div>
    <div class="scheduler-table-wrapper">
      <table class="scheduler-table">
        <thead>
          <tr>
            <th>ID</th>
            <th>{{ t('config.schedulerConfig.jobName') }}</th>
            <th>{{ t('config.schedulerConfig.jobGroup') }}</th>
            <th>{{ t('config.schedulerConfig.jobClass') }}</th>
            <th>{{ t('config.schedulerConfig.cronExpression') }}</th>
            <th>{{ t('config.schedulerConfig.status') }}</th>
            <th>{{ t('config.schedulerConfig.actions') }}</th>
          </tr>
        </thead>
        <tbody>
          <tr v-for="job in filteredJobs" :key="job.id">
            <td>{{ job.id }}</td>
            <td>{{ job.jobName }}</td>
            <td>{{ job.jobGroup }}</td>
            <td :title="job.jobClass">{{ job.jobClass }}</td>
            <td>{{ job.cronExpression }}</td>
            <td>{{ t('config.schedulerConfig.jobStatus.' + job.status) }}</td>
            <td>
              <button class="action-btn" @click="editJob(job)">{{ t('config.schedulerConfig.editJob') }}</button>
              <button class="action-btn" @click="pauseJob(job)" v-if="job.status === 'ACTIVE'">{{ t('config.schedulerConfig.pauseJob') }}</button>
              <button class="action-btn" @click="resumeJob(job)" v-if="job.status === 'PAUSED'">{{ t('config.schedulerConfig.resumeJob') }}</button>
              <button class="action-btn" @click="runJob(job)">{{ t('config.schedulerConfig.runJob') }}</button>
              <button class="action-btn danger" @click="deleteJob(job)">{{ t('config.schedulerConfig.deleteJob') }}</button>
            </td>
          </tr>
        </tbody>
      </table>
    </div>
    <!-- 新建/编辑任务弹窗 -->
    <Modal v-model="showAddModal" :title="modalTitle" @confirm="handleSave">
      <div class="modal-form">
        <div class="form-item">
          <label>
            {{ t('config.schedulerConfig.jobName') }}
            <span class="field-tip" :title="fieldTips.jobName">？</span>
          </label>
          <input v-model="editForm.jobName" type="text" required class="modal-input" />
        </div>
        <div class="form-item">
          <label>
            {{ t('config.schedulerConfig.jobGroup') }}
            <span class="field-tip" :title="fieldTips.jobGroup">？</span>
          </label>
          <input v-model="editForm.jobGroup" type="text" required class="modal-input" />
        </div>
        <div class="form-item">
          <label>
            {{ t('config.schedulerConfig.jobClass') }}
            <span class="field-tip" :title="fieldTips.jobClass">？</span>
          </label>
          <select v-model="editForm.jobClass" class="modal-input" required>
            <option v-for="opt in jobClassOptions" :key="opt.value" :value="opt.value">{{ opt.label }}</option>
          </select>
        </div>
        <div class="form-item">
          <label>
            计划
            <span class="field-tip" :title="fieldTips.cronExpression">？</span>
          </label>
          <div class="plan-row">
            <CustomSelect
              v-model="repeatType"
              :options="repeatOptions"
              :placeholder="'选择重复类型'"
              style="min-width:120px"
            />
            <input
              v-if="repeatType === 'once'"
              v-model="date"
              type="date"
              class="modal-input"
              style="margin-left:8px"
            />
            <input
              v-model="time"
              type="time"
              class="modal-input"
              style="margin-left:8px"
            />
          </div>
          <div v-if="repeatType === 'week'" class="weekdays-row">
            <button
              v-for="d in weekDays"
              :key="d.id"
              :class="['weekday-btn', { active: selectedWeekDays.includes(d.id) }]"
              @click="toggleWeekDay(d.id)"
              type="button"
            >{{ d.name }}</button>
          </div>
          <div v-if="repeatType === 'month'" class="monthdays-row">
            <div class="calendar-grid">
              <template v-for="(row, rowIdx) in calendarRows" :key="rowIdx">
                <div class="calendar-row">
                  <button
                    v-for="d in row"
                    :key="d.id"
                    :class="['monthday-btn', { active: selectedMonthDays.includes(d.id), disabled: d.disabled, special: d.special }]"
                    :disabled="!!d.disabled"
                    @click="!d.disabled && toggleMonthDay(d.id)"
                    @mouseenter="showSpecialTip(d)"
                    @mouseleave="hideSpecialTip"
                  >{{ d.name }}</button>
                </div>
              </template>
            </div>
            <div v-if="specialTip" class="special-tip">{{ specialTip }}</div>
          </div>
          <div class="cron-desc" v-if="cronDesc">
            <Icon icon="carbon:information" style="margin-right:4px" />
            {{ cronDesc }}
          </div>
        </div>
        <!-- 隐藏原始 Cron 输入框，仅用于后端提交 -->
        <input v-model="editForm.cronExpression" type="hidden" />
        <div class="form-item">
          <label>
            {{ t('config.schedulerConfig.jobData') }}
            <span class="field-tip" :title="fieldTips.jobData">？</span>
          </label>
          <textarea v-model="editForm.jobData" rows="2" class="modal-textarea" />
        </div>
        <div class="form-item">
          <label>
            {{ t('config.schedulerConfig.description') }}
            <span class="field-tip" :title="fieldTips.description">？</span>
          </label>
          <textarea v-model="editForm.description" rows="2" class="modal-textarea" />
        </div>
        <div class="form-item">
          <label>
            {{ t('config.schedulerConfig.status') }}
            <span class="field-tip" :title="fieldTips.status">？</span>
          </label>
          <select v-model="editForm.status" class="modal-input">
            <option value="ACTIVE">{{ t('config.schedulerConfig.jobStatus.ACTIVE') }}</option>
            <option value="PAUSED">{{ t('config.schedulerConfig.jobStatus.PAUSED') }}</option>
            <option value="DELETED">{{ t('config.schedulerConfig.jobStatus.DELETED') }}</option>
          </select>
        </div>
      </div>
    </Modal>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, watch } from 'vue'
import { useI18n } from 'vue-i18n'
import { Icon } from '@iconify/vue'
import Modal from '@/components/modal/index.vue'
import CustomSelect from '@/components/select/index.vue'
import { SchedulerApiService, type ScheduleJob } from '@/api/scheduler-api-service'
import dayjs from 'dayjs'

const { t } = useI18n()
const jobs = ref<ScheduleJob[]>([])
const searchQuery = ref('')
const showAddModal = ref(false)
const editForm = ref<Partial<ScheduleJob>>({ jobData: '', description: '' })
const modalTitle = computed(() => editForm.value.id ? t('config.schedulerConfig.editJob') : t('config.schedulerConfig.addJob'))

// 字段含义说明（setup 变量，模板可直接访问）
const fieldTips = {
  jobName: '任务的唯一名称，用于区分不同定时任务',
  jobGroup: '任务分组，可用于分类管理',
  jobClass: '任务执行的类名（需实现Job接口）',
  cronExpression: 'Cron表达式，定义任务的执行时间计划',
  jobData: '任务自定义参数，JSON格式传递给任务',
  description: '任务的详细描述信息',
  status: '任务当前状态（激活/暂停/删除）'
}

// 任务类下拉选项（setup 变量，模板可直接访问）
const jobClassOptions = [
  { value: 'com.alibaba.cloud.ai.example.manus.schedule.job.PlanExecutorJob', label: '执行预定计划' }
]

// 计划相关
const repeatOptions = [
  { id: 'once', name: '不重复' },
  { id: 'day', name: '每天' },
  { id: 'week', name: '每周' },
  { id: 'month', name: '每月' }
]
const repeatType = ref('once')
const date = ref(dayjs().format('YYYY-MM-DD'))
const time = ref('08:00')

const weekDays = [
  { id: '1', name: '周一' },
  { id: '2', name: '周二' },
  { id: '3', name: '周三' },
  { id: '4', name: '周四' },
  { id: '5', name: '周五' },
  { id: '6', name: '周六' },
  { id: '0', name: '周日' }
]
interface MonthDay {
  id: string
  name: string
  special: boolean
  disabled?: boolean
}
const monthDays: MonthDay[] = Array.from({ length: 31 }, (_, i) => ({ id: String(i + 1), name: `${i + 1}号`, special: i + 1 > 28, disabled: false }))
const selectedWeekDays = ref<string[]>(['1'])
const selectedMonthDays = ref<string[]>(['1'])
// 日历式二维数组
const calendarRows = computed<MonthDay[][]>(() => {
  const days: MonthDay[] = monthDays.map(d => ({ ...d }))
  while (days.length < 35) days.push({ id: '', name: '', disabled: true, special: false })
  return Array.from({ length: 5 }, (_, i) => days.slice(i * 7, (i + 1) * 7))
})
const specialTip = ref('')
function showSpecialTip(d: MonthDay) {
  if (d.special && d.id) {
    specialTip.value = `${d.name}：只有部分月份有此日期，选中后仅在有该日期的月份执行`
  }
}
function hideSpecialTip() { specialTip.value = '' }

watch([repeatType, date, time, selectedWeekDays, selectedMonthDays], () => {
  editForm.value.cronExpression = generateCron(
    repeatType.value, date.value, time.value, selectedWeekDays.value, selectedMonthDays.value
  )
})

function generateCron(type: string, dateStr: string, timeStr: string, weekArr: string[], monthArr: string[]) {
  const [hour, minute] = timeStr.split(':').map(Number)
  if (type === 'once') {
    const d = dayjs(dateStr)
    return `0 ${minute} ${hour} ${d.date()} ${d.month() + 1} ?`
  }
  if (type === 'day') {
    return `0 ${minute} ${hour} * * ?`
  }
  if (type === 'week') {
    return `0 ${minute} ${hour} ? * ${weekArr.length ? weekArr.join(',') : '1'}`
  }
  if (type === 'month') {
    return `0 ${minute} ${hour} ${monthArr.length ? monthArr.join(',') : '1'} * ?`
  }
  return ''
}

function toggleWeekDay(id: string) {
  if (selectedWeekDays.value.includes(id)) {
    selectedWeekDays.value = selectedWeekDays.value.filter(d => d !== id)
  } else {
    selectedWeekDays.value.push(id)
  }
}
function toggleMonthDay(id: string) {
  if (selectedMonthDays.value.includes(id)) {
    selectedMonthDays.value = selectedMonthDays.value.filter(d => d !== id)
  } else {
    selectedMonthDays.value.push(id)
  }
}

const cronDesc = computed(() => {
  if (repeatType.value === 'once') {
    return `仅在 ${date.value} ${time.value} 执行一次`
  }
  if (repeatType.value === 'day') {
    return `每天 ${time.value} 执行`
  }
  if (repeatType.value === 'week') {
    const days = selectedWeekDays.value.length
      ? selectedWeekDays.value.map(id => weekDays.find(d => d.id === id)?.name).join('、')
      : '周一'
    return `每周${days} ${time.value} 执行`
  }
  if (repeatType.value === 'month') {
    const days = selectedMonthDays.value.length
      ? selectedMonthDays.value.map(id => `${id}号`).join('、')
      : '1号'
    const hasSpecial = selectedMonthDays.value.some(id => Number(id) > 28)
    return `每月${days} ${time.value} 执行` + (hasSpecial ? '（仅在有该日期的月份执行）' : '')
  }
  return ''
})

const filteredJobs = computed(() => {
  if (!searchQuery.value.trim()) return jobs.value
  const q = searchQuery.value.trim().toLowerCase()
  return jobs.value.filter((job: ScheduleJob) =>
    job.jobName.toLowerCase().includes(q) ||
    job.jobGroup.toLowerCase().includes(q) ||
    job.jobClass.toLowerCase().includes(q)
  )
})

const loadJobs = async () => {
  jobs.value = await SchedulerApiService.getAllJobs()
}
onMounted(loadJobs)

const editJob = (job: ScheduleJob) => {
  editForm.value = { ...job, jobData: job.jobData ?? '', description: job.description ?? '' }
  // 解析 cronExpression 反推 UI（简单场景）
  if (job.cronExpression) {
    const parts = job.cronExpression.split(' ')
    if (parts.length === 5) {
      const [min, hour, day, month, week] = parts
      time.value = `${hour.padStart(2, '0')}:${min.padStart(2, '0')}`
      if (week !== '*' && week !== '?') {
        repeatType.value = 'week'
        selectedWeekDays.value = week.split(',')
      } else if (month !== '*' && day === '1') {
        repeatType.value = 'month'
        selectedMonthDays.value = ['1']
      } else if (day !== '*' && month !== '*') {
        repeatType.value = 'once'
        date.value = `${dayjs().year()}-${month.padStart(2, '0')}-${day.padStart(2, '0')}`
      } else if (day === '*' && month === '*') {
        repeatType.value = 'day'
      }
    }
  }
  showAddModal.value = true
}
const handleSave = async () => {
  // 保证 jobData/description 不为 undefined
  editForm.value.jobData = editForm.value.jobData ?? ''
  editForm.value.description = editForm.value.description ?? ''
  if (editForm.value.id) {
    await SchedulerApiService.updateJob(editForm.value.id, editForm.value)
  } else {
    await SchedulerApiService.addJob(editForm.value)
  }
  showAddModal.value = false
  await loadJobs()
}
const deleteJob = async (job: ScheduleJob) => {
  if (confirm(t('config.schedulerConfig.confirmDelete'))) {
    await SchedulerApiService.deleteJob(job.id)
    await loadJobs()
  }
}
const pauseJob = async (job: ScheduleJob) => {
  if (confirm(t('config.schedulerConfig.confirmPause'))) {
    await SchedulerApiService.pauseJob(job.id)
    await loadJobs()
  }
}
const resumeJob = async (job: ScheduleJob) => {
  if (confirm(t('config.schedulerConfig.confirmResume'))) {
    await SchedulerApiService.resumeJob(job.id)
    await loadJobs()
  }
}
const runJob = async (job: ScheduleJob) => {
  if (confirm(t('config.schedulerConfig.confirmRun'))) {
    await SchedulerApiService.runJobNow(job.id)
    await loadJobs()
  }
}
</script>

<style scoped>
.scheduler-config-panel {
  background: rgba(255,255,255,0.02);
  color: #fff;
  padding: 20px;
}
.scheduler-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 16px;
}
.search-box {
  position: relative;
  margin-bottom: 16px;
}
.search-input {
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 4px;
  padding: 6px 12px 6px 32px;
  color: rgba(255, 255, 255, 0.9);
  width: 220px;
  font-size: 14px;
  transition: all 0.3s;
}
.search-input:focus {
  outline: none;
  border-color: rgba(102, 126, 234, 0.5);
  background: rgba(255, 255, 255, 0.08);
  width: 260px;
}
.search-input::placeholder {
  color: rgba(255, 255, 255, 0.4);
}
.search-icon {
  position: absolute;
  left: 10px;
  top: 50%;
  transform: translateY(-50%);
  font-size: 14px;
  opacity: 0.6;
}
.scheduler-table-wrapper {
  overflow-x: auto;
}
.scheduler-table {
  width: 100%;
  border-collapse: collapse;
  background: rgba(255,255,255,0.03);
  table-layout: fixed;
}
.scheduler-table th, .scheduler-table td {
  padding: 8px 12px;
  border-bottom: 1px solid rgba(255,255,255,0.08);
  text-align: left;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.scheduler-table th:nth-child(1),
.scheduler-table td:nth-child(1) {
  width: 48px;
  min-width: 36px;
  max-width: 60px;
}
.scheduler-table th:nth-child(2),
.scheduler-table td:nth-child(2) {
  min-width: 120px;
  max-width: 220px;
}
.scheduler-table th:nth-child(3),
.scheduler-table td:nth-child(3) {
  width: 120px;
  min-width: 80px;
  max-width: 150px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.scheduler-table th:nth-child(4),
.scheduler-table td:nth-child(4) {
  min-width: 180px;
  max-width: 320px;
}
.scheduler-table th:nth-child(5),
.scheduler-table td:nth-child(5) {
  width: 140px;
  min-width: 90px;
  max-width: 180px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.scheduler-table th:nth-child(6),
.scheduler-table td:nth-child(6) {
  width: 90px;
  min-width: 60px;
  max-width: 120px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.action-btn {
  margin-right: 6px;
  padding: 4px 10px;
  border-radius: 4px;
  border: none;
  background: rgba(102,126,234,0.1);
  color: #fff;
  cursor: pointer;
  transition: background 0.2s;
}
.action-btn.danger {
  background: rgba(234, 102, 102, 0.15);
}
.action-btn:hover {
  background: rgba(102,126,234,0.2);
}
.modal-form {
  display: flex;
  flex-direction: column;
  gap: 18px;
  padding: 8px 2px 0 2px;
}
.form-item {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.modal-input, .modal-textarea, .modal-form select {
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 6px;
  padding: 10px 12px;
  color: rgba(255, 255, 255, 0.9);
  font-size: 14px;
  transition: all 0.3s;
}
select.modal-input {
  background: rgba(255, 255, 255, 0.05);
  color: rgba(255, 255, 255, 0.9);
  border: 1px solid rgba(255, 255, 255, 0.1);
}
select.modal-input:focus {
  outline: none;
  border-color: rgba(102, 126, 234, 0.5);
  background: rgba(255, 255, 255, 0.08);
}
select.modal-input option {
  background: #232946;
  color: #fff;
}
.modal-input:focus, .modal-textarea:focus, .modal-form select:focus {
  outline: none;
  border-color: rgba(102, 126, 234, 0.5);
  background: rgba(255, 255, 255, 0.08);
}
.modal-input::placeholder, .modal-textarea::placeholder {
  color: rgba(255, 255, 255, 0.4);
}
.modal-textarea {
  resize: vertical;
  min-height: 38px;
  font-family: inherit;
}
.plan-row {
  display: flex;
  align-items: center;
  gap: 8px;
}
.cron-desc {
  margin-top: 4px;
  color: #a3bffa;
  font-size: 13px;
  display: flex;
  align-items: center;
}
.weekdays-row, .monthdays-row {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 8px 0;
}
.weekday-btn, .monthday-btn {
  background: rgba(255,255,255,0.08);
  border: 1px solid rgba(102,126,234,0.2);
  border-radius: 4px;
  color: #a3bffa;
  padding: 4px 10px;
  cursor: pointer;
  font-size: 13px;
  transition: all 0.2s;
}
.weekday-btn.active, .monthday-btn.active {
  background: #667eea;
  color: #fff;
  border-color: #667eea;
}
.special-tip {
  color: #ffd700;
  font-size: 13px;
  margin-top: 4px;
}
.calendar-grid {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.calendar-row {
  display: flex;
  gap: 2px;
}
.monthday-btn.disabled {
  background: transparent;
  border: none;
  color: transparent;
  cursor: default;
}
.monthday-btn.special {
  border-color: #ffd700;
  color: #ffd700;
}
.monthday-btn.special.active {
  background: #ffd700;
  color: #222;
  border-color: #ffd700;
}
.field-tip {
  display: inline-block;
  margin-left: 4px;
  color: #a3bffa;
  background: rgba(102,126,234,0.12);
  border-radius: 50%;
  width: 18px;
  height: 18px;
  text-align: center;
  font-size: 13px;
  line-height: 18px;
  cursor: pointer;
  transition: background 0.2s;
}
.field-tip:hover {
  background: #667eea;
  color: #fff;
}
</style> 